package com.windbell.rest.controllers

import org.springframework.web.bind.annotation.RestController
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RequestParam
import org.springframework.web.multipart.MultipartFile
import java.io.File
import java.util.UUID
import java.io.FileOutputStream
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.ResponseBody
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.PathVariable
import org.springframework.http.HttpHeaders
import org.springframework.core.io.Resource
import java.nio.file.Path
import org.springframework.core.io.UrlResource
import java.net.MalformedURLException
import java.nio.file.Paths
import org.springframework.beans.factory.annotation.Autowired
import edu.fudan.mylang.pf.IObjectFactory
import edu.fudan.langlab.domain.document.DocumentStorage
import com.google.common.io.ByteStreams
import javax.servlet.http.HttpServletResponse
import com.windbell.rest.RestRequestInfo
import com.windbell.rest.services.TransactionalRunner
import static com.windbell.rest.services.RestUtil.*

@RestController
class FileUploadController {

	@Autowired TransactionalRunner transactionalRunner
	@Autowired IObjectFactory entities

	@RestRequestInfo(name="上传")
	@PostMapping("/api/upload")
	def uploadFile(@RequestParam("file") MultipartFile file) {
		val tempDir = new File(System.getProperty("java.io.tmpdir"));
		val fileuuid = UUID.randomUUID().toString() + file.getOriginalFilename();
		val stream = new FileOutputStream(new File(tempDir, fileuuid));
		stream.write(file.getBytes());
		stream.close();
		callWithResult[|
			return fileuuid
		]
	}

//TODO: show pic 
	@GetMapping("/files/{filename:.+}")
    @ResponseBody
    def ResponseEntity<Resource> serveFile(@PathVariable String filename) {
        val file = loadAsResource(filename);
        return ResponseEntity.ok().header(HttpHeaders.CONTENT_DISPOSITION,
                "attachment; filename=\"" + file.getFilename() + "\"").body(file);
    }

    def Resource loadAsResource(String filename) {
        try {
        	val rootPath = Paths.get(System.getProperty("java.io.tmpdir"));
            val Path file = rootPath.resolve(filename);
            val Resource resource = new UrlResource(file.toUri());
            if (resource.exists() || resource.isReadable()) {
                return resource;
            }
            else {
                throw new RuntimeException(
                        "Could not read file: " + filename);

            }
        }
        catch (MalformedURLException e) {
            throw new RuntimeException("Could not read file: " + filename, e);
        }
    }
    
    //maybe unsafe ...
 	@GetMapping("/documents/{id}")
    def void getDocument(@PathVariable Long id, HttpServletResponse resp){
    	transactionalRunner.call[|
    		val doc = entities.get(DocumentStorage, id)
    		ByteStreams.copy(doc.getContent().getBinaryStream(),
				resp.getOutputStream());
			resp.flushBuffer()
			return null
    	]
    }

    

}